package com.tl.boot.controller;

import com.tl.boot.async.LocalAsyncHandler;
import com.tl.boot.common.annotation.WithPermission;
import com.tl.boot.common.enums.ResultEnum;
import com.tl.boot.common.utils.PermissionUtil;
import com.tl.boot.entity.common.TokenUtil;
import com.tl.boot.common.vo.ResponseVO;
import com.tl.boot.common.vo.TokenVO;
import com.tl.boot.entity.login.dto.LoginRecordDTO;
import com.tl.boot.entity.login.dto.ReSetPwdDTO;
import com.tl.boot.entity.login.form.LoginForm;
import com.tl.boot.entity.login.form.LogoutForm;
import com.tl.boot.entity.login.form.ResetPWDForm;
import com.tl.boot.entity.user.vo.UserBasicInfoVO;
import com.tl.boot.service.user.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * com.tl.boot.controller -- LoginController
 * Description:
 * Created by joshua_liu <a href="mailto:joshualwork@163.com"></a>
 * On 2019/9/10 18:11
 */
@RestController
@RequestMapping("sys")
@Api(tags = "登录模块")
public class LoginController {
    @Autowired
    private LocalAsyncHandler localAsyncHandler;

    @Autowired
    private SysUserService userService;

    @ApiOperation( value = "用户登录", notes = "传用户名和md5加密后的密码" )
    @ApiImplicitParams( {
            @ApiImplicitParam( name = "loginForm", value = "登录请求对象", required = true,
                    dataType = "LoginForm", paramType = "body" )
    } )
    @PostMapping("login")
    public ResponseVO<TokenVO> login(@RequestBody LoginForm loginForm) {
        //通过用户名匹配密码，匹配成功，用userid生成token，
        UserBasicInfoVO userBasicInfoVO = userService.sysUserBasicInfo(loginForm.getUsername());
        TokenVO tokenVO = null;
        if (userBasicInfoVO != null) {
            Long userId = userBasicInfoVO.getUserId();
            if (loginForm.getPassword().equals(userBasicInfoVO.getPassword())) {
                TokenUtil.clearLoginLimit(userId);
                //异步添加登录记录
                LoginRecordDTO dto = new LoginRecordDTO();
                BeanUtils.copyProperties(userBasicInfoVO, dto);
                localAsyncHandler.addLoginRecord(dto);
                String result = TokenUtil.generateEncryptToken(userId);
                //异步获取用户的角色和权限信息并存进redis
                localAsyncHandler.storeUserPermissionInfo(userId);
                // 返回token
                tokenVO = new TokenVO(result);
            } else {
                if (TokenUtil.allowTryAgain(userId)){
                    return ResponseVO.buildFail(ResultEnum.AUTH_PWD_NOT_MATCH);
                }else {
                    return ResponseVO.buildFail(ResultEnum.AUTH_LOGIN_LIMIT);
                }
            }
        } else {
            return ResponseVO.buildFail(ResultEnum.REQUEST_ILLEGAL);
        }

        return ResponseVO.buildSuccess(tokenVO);
    }

    @ApiOperation( value = "用户登出", notes = "要token，传空json串" )
    @ApiImplicitParams( {
            @ApiImplicitParam( name = "logoutForm", value = "登出请求对象", required = true,
                    dataType = "LogoutForm", paramType = "body" ),
            @ApiImplicitParam( name = "token", value = "鉴权token", required = true, dataType = "String", paramType = "header" ),
    } )
    @PostMapping("auth/logout")
    public ResponseVO logout(@RequestBody LogoutForm logoutForm) {
        TokenUtil.invalidateTokenInfo(logoutForm.getUserId());
        //设置改用户的权限信息失效
        PermissionUtil.invalidatePermissionInfo(logoutForm.getUserId());
        return ResponseVO.buildSuccess();
    }

    @ApiOperation( value = "重置密码", notes = "传密码重置请求对象" )
    @ApiImplicitParams( {
            @ApiImplicitParam( name = "form", value = "密码重置请求对象", required = true,
                    dataType = "ResetPWDForm", paramType = "body" ),
            @ApiImplicitParam( name = "token", value = "鉴权token", required = true, dataType = "String", paramType = "header" ),
    } )
    @PostMapping("auth/pwdReset")
    @WithPermission(role = {"root"})
    public ResponseVO pwdReset(@RequestBody ResetPWDForm form) {
        //只有管理员可以重置密码
        ReSetPwdDTO dto = new ReSetPwdDTO();
        BeanUtils.copyProperties(form,dto);
        userService.resetPwd(dto);
        return ResponseVO.buildSuccess();
    }


}
